package com.ruoyi.common.utils;

import cn.hutool.core.map.MapBuilder;
import cn.hutool.core.util.StrUtil;
import com.ruoyi.common.config.RuoYiConfig;

import java.util.Map;

/**
 * @author wangxianl
 * createTime: 2020-11-9.
 * description: 地区码工具类
 */
public class AreaUtils {

    /**
     * 默认是否使用地区码
     */
    public static final boolean USE_LOCALE_DEFAULT = true;

    /**
     * 根地区码
     */
    public static final String ROOT_AREA_CODE = RuoYiConfig.getRootAreaCode();

    public static final String ROOT_AREA_NAME = RuoYiConfig.getRootAreaName();

    /**
     * 当前系统最大级别
     */
    public static final int MAX_LEVEL = 5;

    /**
     * 地区级别
     */
    public static class Level {
        //全国
        public static final int GUO = 0;
        //省级
        public static final int SHENG = 1;
        //市级
        public static final int SHI = 2;
        //县级
        public static final int XIAN = 3;
        //镇街
        public static final int ZHEN = 4;
        //村级
        public static final int CUN = 5;
    }

    /**
     * 地区编码长度
     */
    public static class CodeLength {
        //全国
        public static final int GUO = 0;
        //省级
        public static final int SHENG = 2;
        //市级
        public static final int SHI = 4;
        //县级
        public static final int XIAN = 6;
        //镇街
        public static final int ZHEN = 9;
        //村级
        public static final int CUN = 12;
    }

    /**
     * 根据级别获取地区码长度
     *
     * @param level 地区级别
     */
    public static int getLengthByLevel(int level) {
        switch (level) {
            case Level.GUO:
                return CodeLength.GUO;
            case Level.SHENG:
                return CodeLength.SHENG;
            case Level.SHI:
                return CodeLength.SHI;
            case Level.XIAN:
                return CodeLength.XIAN;
            case Level.ZHEN:
                return CodeLength.ZHEN;
            case Level.CUN:
                return CodeLength.CUN;
            default:
                return 0;
        }
    }

    /**
     * 根据地区码长度获取地区级别
     *
     * @param length 地区码长度
     */
    public static int getLevelByLength(int length) {
        switch (length) {
            case CodeLength.GUO:
                return Level.GUO;
            case CodeLength.SHENG:
                return Level.SHENG;
            case CodeLength.SHI:
                return Level.SHI;
            case CodeLength.XIAN:
                return Level.XIAN;
            case CodeLength.ZHEN:
                return Level.ZHEN;
            case CodeLength.CUN:
                return Level.CUN;
            default:
                return 0;
        }
    }

    /**
     * 截取地区码
     *
     * @param code  地区编码
     * @param level 截取级别
     */
    public static String getCodeByLevel(String code, int level) {
        int levelLen = getLengthByLevel(level);
        //截取字符串
        if (levelLen > code.length()) {
            //要截取的长度大于本身长度,证明级别超过,返回null
            return null;
        }
        return code.substring(0, levelLen);
    }

    /**
     * 获取使用的地区表名
     *
     * @param useLocale 是否使用本地地区码
     */
    public static String getAreaTable(boolean useLocale) {
        return useLocale ? "sys_area_locale" : "sys_area_standard";
    }

    /**
     * 获取每一级的编码,包含level和parentCode
     *
     * @return 构建的map
     */
    public static Map<String, Object> getEachLevelCodeMap(String code) {
        MapBuilder<String, Object> builder = MapBuilder.create();
        //级别
        int level = getLevelByLength(code.length());
        builder.put("level", level);
        //父级编码
        builder.put("parentCode", getCodeByLevel(code, level - 1));
        //各级编码
        for (int i = 1; i <= MAX_LEVEL; i++) {
            builder.put("code" + i, getCodeByLevel(code, i));
        }
        return builder.build();
    }

    /**
     * 根据全长度的编码获取端编码
     *
     * @param fullCode 长编码
     */
    public static String getShortCode(String fullCode) {
        if (StrUtil.isEmpty(fullCode)) {
            return fullCode;
        }
        //截取到最大层级
        int maxLength = getLengthByLevel(MAX_LEVEL);
        if (fullCode.length() > maxLength) {
            fullCode = fullCode.substring(0, maxLength);
        }
        int length = fullCode.length();
        //镇街和村级的空编码
        String cEmpty = "000";
        //省市县的空编码
        String sEmpty = "00";
        //是否为村级==========================================================
        if (length >= CodeLength.CUN) {
            String cunCode = fullCode.substring(CodeLength.ZHEN, CodeLength.CUN);
            if (!cunCode.equals(cEmpty)) {
                return getCodeByLevel(fullCode, Level.CUN);
            }
        }
        //是否为镇街级
        if (length >= CodeLength.ZHEN) {
            String zhenCode = fullCode.substring(CodeLength.XIAN, CodeLength.ZHEN);
            if (!zhenCode.equals(cEmpty)) {
                return getCodeByLevel(fullCode, Level.ZHEN);
            }
        }
        //是否为县级
        if (length >= CodeLength.XIAN) {
            String xianCode = fullCode.substring(CodeLength.SHI, CodeLength.XIAN);
            if (!xianCode.equals(sEmpty)) {
                return getCodeByLevel(fullCode, Level.XIAN);
            }
        }
        //是否为市级
        if (length >= CodeLength.SHI) {
            String shiCode = fullCode.substring(CodeLength.SHENG, CodeLength.SHI);
            if (!shiCode.equals(sEmpty)) {
                return getCodeByLevel(fullCode, Level.SHI);
            }
        }
        //省级
        return getCodeByLevel(fullCode, Level.SHENG);
    }
}
